import logging
from logging.handlers import SMTPHandler, RotatingFileHandler

from flask import Flask
from config import Config
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_login import LoginManager
from flask_mail import Mail
from flask_bootstrap import Bootstrap
# check .flaskenv setting
import os
flask_env =os.getenv('TEST_ENV')
flask_run_port =os.getenv('FLASK_RUN_PORT')
print(flask_env, flask_run_port)


# 请注意，这些更改非常简单，每次更改都只会影响很少的代码。 
# 我试图在编写应用每个部分的时候，不做任何有关其他部分如何工作的假设，
# 这使我可以编写更易于扩展和测试的且兼具模块化和健壮性的应用，
# 并且不太可能失败或出现BUG。



###############     应用实例app      ###############
app = Flask(__name__)
# 配置
app.config.from_object(Config)

###############     插件 创建和初始化      ###############
# 添加一个db对象来表示数据库
db = SQLAlchemy(app)
# 添加数据库迁移引擎migrate
migrate = Migrate(app, db)
login = LoginManager(app)
# 'login'值是登录视图函数（endpoint）名，
# 换句话说该名称可用于url_for()函数的参数并返回对应的URL
login.login_view = 'login'

# Mail
mail = Mail(app)

# Bootstrap: CSS框架之一是由Twitter推出的Bootstrap
bootstrap = Bootstrap(app)

###############     日志写入文件&邮件#&终端     ###############
if not app.debug:
    if app.config['MAIL_SERVER']:
        auth = None
        if app.config['MAIL_USERNAME'] or app.config['MAIL_PASSWORD']:
            auth = (app.config['MAIL_USERNAME'], app.config['MAIL_PASSWORD'])
        secure = None
        if app.config['MAIL_USE_TLS']:
            secure = ()
        mail_handler = SMTPHandler(
            mailhost=(app.config['MAIL_SERVER'], app.config['MAIL_PORT']),
            fromaddr='no-reply@' + app.config['MAIL_SERVER'],
            toaddrs=app.config['ADMINS'], subject='Microblog Failure',
            credentials=auth, secure=secure)
        mail_handler.setLevel(logging.ERROR)
        app.logger.addHandler(mail_handler)

    if not os.path.exists('logs'):
        os.mkdir('logs')
    file_handler = RotatingFileHandler('logs/microblog.log', maxBytes=10240,
                                    backupCount=10)
    file_handler.setFormatter(logging.Formatter(
        '%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d]'))
    file_handler.setLevel(logging.INFO)
    app.logger.addHandler(file_handler)

    app.logger.setLevel(logging.INFO)
    app.logger.info('Microblog startup')




###############     最下面导入routes & models     ###############
# routes模块是在底部导入的，而不是在脚本的顶部。
# 最下面的导入是解决循环导入的问题
# routes模块需要导入在这个脚本中定义的app变量，
# 因此将routes的导入放在底部可以避免由于这两个文件之间的相互引用而导致的错误
from app import routes
# models模块用来定义数据库结构
from app import models
# 错误处理
from app import errors